#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <string>
#include <cstring>
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include "Log.hpp"
#include"ThreadPool.hpp"


Log lg;

using namespace std;

#define defaultPort 8888
#define defaultIp "0.0.0.0"

enum
{
    USAGEERR = 1,
    SOCKETERR,
    BINDERR,
    LISTENERR
};

class ThreadData{
public:
    ThreadData(int sockfd)
    :sockfd_(sockfd)
    {}

public:
    int sockfd_;
};

class TcpServer
{
public:
    TcpServer(string ip = defaultIp, uint16_t port = defaultPort)
        : port_(port), ip_(ip)
    {
        t.start();
    }

    void Init()
    {
        listenfd_ = socket(AF_INET, SOCK_STREAM, 0);
        if (listenfd_ < 0)
        {
            lg(Fatal, "socket Fail,sockfd:%d,code:%d,strerror:%s", listenfd_, errno, strerror(errno));
            exit(SOCKETERR);
        }
        lg(Info, "socket Success,listenkfd:%d,code:%d,str:%s", listenfd_, errno, strerror(errno));

        struct sockaddr_in lock;
        socklen_t len = sizeof(lock);
        memset(&lock, 0, len);
        lock.sin_family = AF_INET;
        lock.sin_port = htons(port_);
        // inet_pton(AF_INET, ip_.c_str(), &lock.sin_addr);

        char str[32] = {0};
        inet_pton(AF_INET, ip_.c_str(), &lock.sin_addr);

        int n = bind(listenfd_, (const sockaddr *)&lock, len);
        if (n < 0)
        {
            lg(Fatal, "bind Fail,code:%d,str:%s", listenfd_, errno, strerror(errno));
            exit(BINDERR);
        }
        lg(Info, "bind success,code:%d,str:%s", errno, strerror(errno));

        n = listen(listenfd_, 0);
        if (n < 0)
        {
            lg(Fatal, "listen fail,errno:%d,strerror:%s", errno, strerror(errno));
            exit(LISTENERR);
        }
        lg(Info, "listen success,code:%d,str:%s", errno, strerror(errno));
    }


    //线程池版
    void Strat()
    {
        while (1)
        {
            // client.sin_family=AF_INET;
            // uint16_t port = ntohs(client.sin_port);
            // char ip[32];
            // //inet_ntop(AF_INET, &(client.sin_addr), ip, sizeof(ip));
            // printf("[%s][%d] connect ...\n", port, ip);

            // struct sockaddr_in client;
            // socklen_t len = sizeof(client);
            // memset(&client, 0, len);
            // int sockfd = accept(listenfd_, (struct sockaddr *)&client, &len);
            
            // uint16_t port=ntohs(client.sin_port);
            // string ip=to_string(ntohl(client.sin_addr.s_addr));
            // lg(Info,"get a new connect:%d,ip:%s,sort:%d",sockfd,ip.c_str(),port);
            // t.push(sockfd);
        }
    }

    ~TcpServer()
    {}

private:
    int listenfd_;
    uint16_t port_;
    std::string ip_;
    Threadpool<int> t;
};
